Module adminConnections
    Sub acceptAdminConnections()
        While True
            Dim admin As TcpClient
            log.write("Listening for admin clients")
            admin = adminSocket.AcceptTcpClient
            admins.newClient(admin, True)
            log.write("New admin client connected and threaded")
        End While
    End Sub

    Sub handleAdminClient()
        Dim net As New ernNetwork.Server(admins.clients(admins.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).connection)
        Dim ip As Net.IPEndPoint = admins.clients(admins.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).connection.Client.RemoteEndPoint
        Dim msg As protocol

        log.write("Waiting for handshake from new admin client")
        If net.handshake() Then
            log.write("Admin client successfully shook my hand")
        Else
            log.write("ERROR: Admin client failed the handshake, so disconnecting and aborting thread")
            admins.clients(admins.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).connection.Close()
            Threading.Thread.CurrentThread.Abort()
        End If

        'main loop
        While True
            msg.message = ""
            msg.type = protocolType.BLANK

            If Not admins.clients(admins.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation Then
                If net.hasData Then
                    admins.clients(admins.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation = True
                    net.getMessage(msg)
                    handleAdminMessage(msg, admins.clients(admins.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())), net)
                    admins.clients(admins.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation = False
                End If
            End If
            Threading.Thread.Sleep(1000)
        End While
    End Sub

    Public Sub handleAdminMessage(ByVal msg As protocol, ByVal c As ERN_Server.ernClients, ByRef net As ernNetwork.server)
        Dim strings() As String
        Dim subStrings() As String
        Dim item As String
        Dim itemsA() As String
        Dim itemsB() As String
        Dim i As Integer
        Dim sendMessageBack As Boolean = True

        If msg.type = protocolType.A_buildComputerTree Then
            msg.type = protocolType.SA_buildComputerTree
            msg.message = sql.getComputerGroups(msg.message)
        ElseIf msg.type = protocolType.A_newComputerGroup Then
            msg.type = protocolType.SA_newComputerGroup
            msg.message = sql.newComputerGroup(msg.message)
        ElseIf msg.type = protocolType.A_deleteComputerGroup Then
            msg.type = protocolType.SA_deleteComputerGroup
            msg.message = sql.delComputerGroup(msg.message)
        ElseIf msg.type = protocolType.A_editComputerGroup Then
            msg.type = protocolType.SA_editComputerGroup
            msg.message = sql.editComputerGroup(msg.message)
        ElseIf msg.type = protocolType.A_listGroupMembers Then
            strings = sql.listGroupMembers(msg.message)
            If Not strings Is Nothing Then
                For i = 0 To strings.Length - 1
                    msg.type = protocolType.SA_listGroupMembersItem
                    msg.message = strings(i)
                    net.sendMessage(msg)
                    net.getMessage(msg)
                Next
            End If
            msg.type = protocolType.SA_listGroupMembersEnd
            msg.message = "ok"
        ElseIf msg.type = protocolType.A_changeComputerGroup Then
            msg.type = protocolType.SA_changeComputerGroup
            msg.message = sql.changeComputerGroup(msg.message)
        ElseIf msg.type = protocolType.A_renameComputers Then
            i = 0
            strings = Split(msg.message, "::")
            ReDim itemsA(strings.Length - 1)
            ReDim itemsB(strings.Length - 1)
            For Each item In strings
                subStrings = Split(item, ":")
                itemsA(i) = subStrings(0)
                itemsB(i) = subStrings(1)
                i = i + 1
            Next
            msg.type = protocolType.SA_renameComputers
            msg.message = sql.scheduleClientAction(protocolType.A_renameComputers, itemsA, itemsB)
        ElseIf msg.type = protocolType.A_getPolicy Then
            Dim policy As policyType

            msg.type = protocolType.SA_getPolicy
            policy = sql.getPolicyDetails(msg.message)
            With policy
                msg.message = .id
                msg.message = msg.message & "::" & .name
                msg.message = msg.message & "::" & .checkInTime
                msg.message = msg.message & "::" & .rebootPolicy.everyFewMinutes
                msg.message = msg.message & "::" & .rebootPolicy.time1
                msg.message = msg.message & "::" & .rebootPolicy.useTime1
                msg.message = msg.message & "::" & .rebootPolicy.time2
                msg.message = msg.message & "::" & .rebootPolicy.useTime2
                msg.message = msg.message & "::" & .rebootPolicy.time3
                msg.message = msg.message & "::" & .rebootPolicy.useTime3
                msg.message = msg.message & "::" & .rebootPolicy.rebootSchedule
                msg.message = msg.message & "::" & .rebootPolicy.scheduledRebootDay
                msg.message = msg.message & "::" & .auPolicy.enabled
                msg.message = msg.message & "::" & .auPolicy.day
                msg.message = msg.message & "::" & .auPolicy.time
            End With
        ElseIf msg.type = protocolType.A_setPolicy Then
            Dim policy As policyType

            strings = Split(msg.message, "::")
            With policy
                .id = strings(0)
                .name = strings(1)
                .checkInTime = strings(2)
                .rebootPolicy.everyFewMinutes = strings(3)
                .rebootPolicy.time1 = strings(4)
                .rebootPolicy.useTime1 = strings(5)
                .rebootPolicy.time2 = strings(6)
                .rebootPolicy.useTime2 = strings(7)
                .rebootPolicy.time3 = strings(8)
                .rebootPolicy.useTime3 = strings(9)
                .rebootPolicy.rebootSchedule = strings(10)
                .rebootPolicy.scheduledRebootDay = strings(11)
                .auPolicy.enabled = strings(12)
                .auPolicy.day = strings(13)
                .auPolicy.time = strings(14)
            End With
            sql.setPolicyDetails(policy)
            msg.message = policy.id
            msg.type = protocolType.SA_setPolicy
        ElseIf msg.type = protocolType.A_applyPolicyToGroup Then
            strings = Split(msg.message, "::")
            sql.applyPolicyToGroup(strings(0), strings(1))
            msg.message = "ok"
        ElseIf msg.type = protocolType.A_forceClientReboot Then
            strings = Split(msg.message, "::")
            For i = 0 To clients.clients.Length - 1
                If strings(0) = clients.clients(i).guid Then
                    'tell client to reboot and pass along the delay
                    msg.type = protocolType.S_forceClientReboot
                    msg.message = strings(1)
                    net.sendTargetedMessage(msg, clients.clients(i).connection)
                    sendMessageBack = False
                End If
            Next
        ElseIf msg.type = protocolType.A_newAutoUpdateInfo Then
            item = msg.message
            i = sql.newAutoUpdatePatch(msg.message)
            msg.message = i
            msg.type = protocolType.SA_newAutoUpdateID
            net.sendMessage(msg)
            itemsA = Split(item, "::")
            item = filesLocationAutoUpdate & IO.Path.GetFileNameWithoutExtension(IO.Path.GetRandomFileName()) & IO.Path.GetExtension(itemsA(0))
            While IO.File.Exists(item)
                Application.DoEvents()
                item = filesLocationAutoUpdate & IO.Path.GetFileNameWithoutExtension(IO.Path.GetRandomFileName()) & IO.Path.GetExtension(itemsA(0))
            End While

            net.getFile(item, itemsA(3))
            If MD5Hash(item) = itemsA(4) Then
                sql.updateAutoUpdatePatchFilename(i, IO.Path.GetFileName(item))
                msg.type = protocolType.SA_newAutoUpdateID
                msg.message = i
                sendMessageBack = True
            Else
                sql.deleteAUItem(i)
                IO.File.Delete(item)
                msg.type = protocolType.SA_ERROR
                msg.message = "File transfer error!"
                sendMessageBack = True
            End If
        ElseIf msg.type = protocolType.A_editAutoUpdateInfo Then
            strings = Split(msg.message, "::")
            If strings.Length = 3 Then
                sql.updateAutoUpdatePatchInfo(strings(0), strings(1), strings(2))
            Else
                sql.updateAutoUpdatePatchInfo(strings(0), strings(1), strings(2), strings(3))
            End If
            msg.type = protocolType.SA_editAutoUpdateInfoACK
            msg.message = ""
        ElseIf msg.type = protocolType.A_startAutoUpdateList Then
            strings = sql.getAutoUpdateList()
            For i = 0 To strings.Length - 1
                msg.type = protocolType.SA_autoUpdateItem
                msg.message = strings(i)
                net.sendMessage(msg)
                net.getMessage(msg)
            Next
            msg.type = protocolType.SA_endAutoUpdateList
            msg.message = ""
        ElseIf msg.type = protocolType.A_startAUInstallList Then
            strings = sql.getAUInstallList(msg.message)
            For i = 0 To strings.Length - 1
                msg.type = protocolType.SA_AUInstallItem
                msg.message = strings(i)
                net.sendMessage(msg)
                net.getMessage(msg)
            Next
            msg.type = protocolType.SA_endAUInstallList
            msg.message = ""
        ElseIf msg.type = protocolType.A_deleteAUItem Then
            sql.deleteAUItem(msg.message)
            msg.type = protocolType.SA_deletedAUItem
            msg.message = ""
        ElseIf msg.type = protocolType.A_setAUPublishDefaults Then
            itemsA = Split(msg.message, "::")
            sql.setAUPublishDefaults(itemsA(0), itemsA(1), itemsA(2), itemsA(3), itemsA(4))
            sendMessageBack = False
        ElseIf msg.type = protocolType.A_getAUPublishDefaults Then
            itemsA = sql.getAUPublishDefaults
            msg.message = itemsA(0) & "::" & itemsA(1) & "::" & itemsA(2)
            msg.type = protocolType.SA_sendAUPublishDefaults
        ElseIf msg.type = protocolType.A_getClientDetails Then
            msg.message = sql.getClientDetails(msg.message)
            msg.type = protocolType.SA_clientDetails
        Else
            msg.type = protocolType.BLANK
            msg.message = "ERROR"
        End If

        If sendMessageBack Then net.sendMessage(msg)
    End Sub
End Module
